package com.shlh.saas.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shlh.saas.common.Result;
import com.shlh.saas.common.UserContext;
import com.shlh.saas.entity.UserBalance;
import com.shlh.saas.model.dto.LinkedInQueryDTO;
import com.shlh.saas.entity.linkedin.LinkedInUser;
import com.shlh.saas.entity.linkedin.LinkedInUserEs;
import com.shlh.saas.service.UserBalanceService;
import com.shlh.saas.service.WorkbenchStatsService;
import com.shlh.saas.service.linkedin.LinkedInUserService;
import com.shlh.saas.util.ExcelUtils;
import com.shlh.saas.service.ExportRecordService;
import com.shlh.saas.util.FileUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.IOException;

/**
 * LinkedIn数据控制器
 */
@RestController
@RequestMapping("/linkedin")
@Slf4j
public class LinkedInController {

    @Autowired
    private LinkedInUserService linkedInUserService;

    @Autowired
    private WorkbenchStatsService workbenchStatsService;

    @Autowired
    private UserBalanceService userBalanceService;

    @Autowired
    private ExportRecordService exportRecordService;

    /**
     * 分页查询LinkedIn数据（ES查询）
     */
    @PostMapping("/list")
    public Result getLinkedInDataList(@RequestBody LinkedInQueryDTO queryDTO) {
        log.info("LinkedIn分页查询请求（ES查询）: {}", queryDTO);

        try {
            // 获取当前用户ID
            Long userId = UserContext.getUserId();

            // 获取页码和每页大小
            int page = queryDTO.getPage() != null ? queryDTO.getPage() : 1;
            int size = queryDTO.getSize() != null ? queryDTO.getSize() : 10;

            // 第一页不扣除额度，免费查看
            if (page == 1) {
                // 使用ES查询
                Page<LinkedInUserEs> resultPage = linkedInUserService.getLinkedInDataPageFromES(queryDTO);

                // 增加搜索次数统计
                workbenchStatsService.incrementLinkedinSearchCount(userId);

                Map<String, Object> data = new HashMap<>();
                data.put("total", resultPage.getTotal());
                data.put("list", resultPage.getRecords());
                data.put("size", resultPage.getSize());
                data.put("current", resultPage.getCurrent());

                log.info("LinkedIn ES查询完成（第一页免费），返回 {} 条记录，总数: {}",
                        resultPage.getRecords().size(), resultPage.getTotal());

                return Result.success(data);
            } else {
                // 检查用户余额
                UserBalance userBalance = userBalanceService.getByUserId(userId);
                if (userBalance == null || userBalance.getViewRecordsRemaining() < size) {
                    return Result.error("您的查看记录余额不足，请充值后再查看");
                }

                // 使用ES查询
                Page<LinkedInUserEs> resultPage = linkedInUserService.getLinkedInDataPageFromES(queryDTO);

                // 扣除用户查看记录余额
                userBalanceService.deductViewRecords(userId, resultPage.getRecords().size());

                // 增加搜索次数统计
                workbenchStatsService.incrementLinkedinSearchCount(userId);

                Map<String, Object> data = new HashMap<>();
                data.put("total", resultPage.getTotal());
                data.put("list", resultPage.getRecords());
                data.put("size", resultPage.getSize());
                data.put("current", resultPage.getCurrent());

                log.info("LinkedIn ES查询完成（扣费页面），返回 {} 条记录，总数: {}, 扣除余额: {}",
                        resultPage.getRecords().size(), resultPage.getTotal(), resultPage.getRecords().size());

                return Result.success(data);
            }

        } catch (Exception e) {
            log.error("LinkedIn分页查询失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 获取LinkedIn联系人详情
     */
    @GetMapping("/detail/{id}")
    public Result getLinkedInDataDetail(@PathVariable Integer id) {
        LinkedInUser data = linkedInUserService.getLinkedInDataById(id);
        if (data == null) {
            return Result.error("联系人不存在");
        }
        return Result.success(data);
    }

    /**
     * 获取符合条件的记录总数（ES查询）
     */
    @PostMapping("/count")
    public Result countLinkedInData(@RequestBody LinkedInQueryDTO queryDTO) {
        log.info("计算符合条件的LinkedIn数据数量（ES查询），参数: {}", queryDTO);

        try {
            // 使用ES计数查询
            long count = linkedInUserService.countLinkedInDataFromES(queryDTO);

            // 限制最大返回数量为5万
            if (count > 50000) {
                count = 50000;
            }

            Map<String, Object> result = new HashMap<>();
            result.put("count", count);

            log.info("LinkedIn ES计数查询完成，总数: {}", count);
            return Result.success(result);

        } catch (Exception e) {
            log.error("LinkedIn计数查询失败", e);
            return Result.error("计数查询失败: " + e.getMessage());
        }
    }

    /**
     * 导出LinkedIn数据
     */
    @PostMapping("/export")
    public void exportLinkedInData(
            HttpServletResponse response,
            @RequestBody LinkedInQueryDTO queryDTO,
            @RequestParam(required = true) Integer exportCount,
            @RequestParam(required = false) String selectedFields,
            @RequestParam(required = false, defaultValue = "zh") String language,
            @RequestParam(required = false, defaultValue = "1") Integer currentPage) {
        log.info("导出LinkedIn数据，参数: {}, 导出数量: {}, 选中字段: {}, 语言: {}, 当前页: {}",
                queryDTO, exportCount, selectedFields, language, currentPage);
        try {
            // 获取当前用户ID
            Long userId = UserContext.getUserId();

            // 处理字段选择（支持国际化）
            Map<String, String> fieldMapping = createFieldMapping(language);
            String[] selectedFieldArray;
            String[] selectedColumnNames;

            if (selectedFields != null && !selectedFields.trim().isEmpty()) {
                // 解析选中的字段
                String[] requestedFields = selectedFields.split(",");
                List<String> validFields = new ArrayList<>();
                List<String> validColumnNames = new ArrayList<>();

                for (String field : requestedFields) {
                    field = field.trim();
                    if (fieldMapping.containsKey(field)) {
                        validFields.add(field);
                        validColumnNames.add(fieldMapping.get(field));
                    } else {
                        log.warn("无效的字段名: {}", field);
                    }
                }

                if (validFields.isEmpty()) {
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                    response.getWriter().write("{\"message\":\"没有有效的字段被选中，请至少选择一个有效字段\"}");
                    return;
                }

                selectedFieldArray = validFields.toArray(new String[0]);
                selectedColumnNames = validColumnNames.toArray(new String[0]);
                log.info("有效字段数量: {}, 字段列表: {}", validFields.size(), validFields);
            } else {
                // 如果没有指定字段，使用默认字段
                selectedFieldArray = getDefaultFields();
                selectedColumnNames = getDefaultColumnNames(language);
                log.info("使用默认字段进行导出");
            }

            // 自动确定标红字段（重要字段）
            String[] highlightFieldArray = getHighlightFields(selectedFieldArray);
            log.info("自动标红字段数量: {}, 标红字段列表: {}", highlightFieldArray.length, Arrays.toString(highlightFieldArray));

            // 检查用户余额
            UserBalance userBalance = userBalanceService.getByUserId(userId);
            if (userBalance == null || userBalance.getExportQuotaRemaining() < exportCount) {
                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.getWriter().write("{\"message\":\"您的导出次数余额不足，请充值后再导出\"}");
                return;
            }

            // 限制最大导出数量为5万
            if (exportCount > 50000) {
                exportCount = 50000;
            }

            // 设置导出限制和起始页
            queryDTO.setLimit(exportCount);

            // 如果指定了当前页，设置查询的起始位置
            if (currentPage > 1) {
                log.info("从第{}页开始导出数据", currentPage);
                // 设置查询的起始位置（页码从1开始，但ES查询的offset从0开始）
                queryDTO.setPageNum(currentPage - 1);
            }

            // 使用ES两阶段查询获取数据
            List<LinkedInUser> dataList = linkedInUserService.exportLinkedInDataFromES(queryDTO);
            log.info("ES两阶段查询完成，获取到 {} 条数据准备导出", dataList.size());

            if (dataList.isEmpty()) {
                response.setContentType("application/json;charset=UTF-8");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                response.getWriter().write("{\"message\":\"没有找到符合条件的数据\"}");
                return;
            }

            // 扣除用户导出次数余额
            userBalanceService.deductExportQuota(userId, dataList.size());

            // 增加导出次数统计
            workbenchStatsService.incrementLinkedinExportCount(userId, dataList.size());

            // 设置导出文件名和表头（使用动态字段，支持国际化）
            String fileNamePrefix = "en".equals(language) ? "LinkedIn_Data" : "LinkedIn数据";
            String fileName = fileNamePrefix + "_" + System.currentTimeMillis() + ".xlsx";

            // 获取当前时间戳作为文件名一部分
            String filePath = "/export/" + fileName;

            // 计算文件大小（以KB为单位）
            String fileSize = FileUtils.estimateExcelSize(dataList.size()) + "KB";

            // 保存导出记录
            exportRecordService.addExportRecord(
                    userId,
                    fileName,
                    "linkedin", // 数据来源
                    fileSize,
                    dataList.size(),
                    filePath
            );

            // 设置响应头部信息，防止客户端浏览器超时
            response.setHeader("Connection", "Keep-Alive");
            response.setHeader("Proxy-Connection", "Keep-Alive");

            // 使用优化版本的导出方法（使用临时文件和流式处理）
            if (dataList.size() > 10000) {
                // 大数据量使用优化版导出方法
                log.info("数据量大于10000，使用优化版导出方法");
                ExcelUtils.exportExcelWithHighlightOptimized(response, dataList, "LinkedIn用户数据",
                        selectedColumnNames, selectedFieldArray, highlightFieldArray);
            } else {
                // 小数据量使用普通导出方法
                ExcelUtils.exportExcelWithHighlight(response, dataList, "LinkedIn用户数据",
                        selectedColumnNames, selectedFieldArray, highlightFieldArray);
            }
            log.info("成功导出LinkedIn数据，包含字段: {}，自动标红字段: {}",
                    Arrays.toString(selectedColumnNames), Arrays.toString(highlightFieldArray));

        } catch (Exception e) {
            log.error("导出LinkedIn数据失败", e);
            try {
                // 只有在响应尚未提交时才尝试重置响应
                if (!response.isCommitted()) {
                    response.reset();
                    response.setContentType("application/json;charset=UTF-8");
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.getWriter().write("{\"message\":\"导出数据失败: " + e.getMessage() + "\"}");
                } else {
                    log.warn("无法发送错误响应，因为响应已经提交");
                }
            } catch (IOException ex) {
                log.error("写入错误响应失败", ex);
            }
        }
    }

    /**
     * 关键词搜索API（ES查询）
     */
    @GetMapping("/search")
    public Result search(@RequestParam(required = false) String keyword,
                         @RequestParam(defaultValue = "0") int page,
                         @RequestParam(defaultValue = "10") int size,
                         @RequestParam(required = false) String companyName,
                         @RequestParam(required = false) String jobTitle,
                         @RequestParam(required = false) String industry,
                         @RequestParam(required = false) String country,
                         @RequestParam(required = false) String contactMethod,
                         @RequestParam(required = false) String companySize) {
        log.info("LinkedIn关键词搜索（ES查询）: keyword={}, page={}, size={}, companyName={}, jobTitle={}, industry={}, location={}, contactMethod={}, companySize={}",
                keyword, page, size, companyName, jobTitle, industry, country, contactMethod, companySize);

        try {
            // 获取当前用户ID
            Long userId = UserContext.getUserId();

            // 第一页不扣除额度，免费查看
            if (page == 0) {
                int offset = page * size;

                // 使用ES筛选搜索
                Page<LinkedInUserEs> esPage = linkedInUserService.searchByKeywordFromES(
                        keyword, offset, size, companyName, jobTitle, industry,
                        country, contactMethod, companySize
                );

                // 统计符合条件的总数
                long total = linkedInUserService.countByKeywordFromES(
                        keyword, companyName, jobTitle, industry,
                        country, contactMethod, companySize
                );

                // 增加搜索次数统计
                workbenchStatsService.incrementLinkedinSearchCount(userId);

                Map<String, Object> data = new HashMap<>();
                data.put("total", total);
                data.put("list", esPage.getRecords());
                data.put("size", esPage.getSize());
                data.put("current", esPage.getCurrent());

                log.info("LinkedIn ES搜索完成（第一页免费），返回 总数total: {},list: {},size: {},current: {}",
                        total, esPage.getRecords(), esPage.getSize(), esPage.getCurrent());

                return Result.success(data);
            } else {
                // 检查用户余额
                UserBalance userBalance = userBalanceService.getByUserId(userId);
                if (userBalance == null || userBalance.getViewRecordsRemaining() < size) {
                    return Result.error("您的查看记录余额不足，请充值后再查看");
                }

                int offset = page * size;

                // 使用ES筛选搜索
                Page<LinkedInUserEs> esPage = linkedInUserService.searchByKeywordFromES(
                        keyword, offset, size, companyName, jobTitle, industry,
                        country, contactMethod, companySize
                );

                // 扣除用户查看记录余额
                userBalanceService.deductViewRecords(userId, esPage.getRecords().size());

                // 增加搜索次数统计
                workbenchStatsService.incrementLinkedinSearchCount(userId);

                // 统计符合条件的总数
                long total = linkedInUserService.countByKeywordFromES(
                        keyword, companyName, jobTitle, industry,
                        country, contactMethod, companySize
                );

                Map<String, Object> data = new HashMap<>();
                data.put("total", total);
                data.put("list", esPage.getRecords());
                data.put("size", esPage.getSize());
                data.put("current", esPage.getCurrent());

                log.info("LinkedIn ES搜索完成（扣费页面），返回 {} 条记录，总数: {}, 扣除余额: {}",
                        esPage.getRecords().size(), total, esPage.getRecords().size());

                return Result.success(data);
            }

        } catch (Exception e) {
            log.error("LinkedIn关键词搜索失败", e);
            return Result.error("搜索失败: " + e.getMessage());
        }
    }

    /**
     * 关键词自动补全建议
     */
    @GetMapping("/suggestions")
    public Result getSuggestions(@RequestParam String keyword) {
        List<String> suggestions = linkedInUserService.getSuggestions(keyword);
        return Result.success(suggestions);
    }

    /**
     * 获取LinkedIn联系人完整敏感信息
     */
    @GetMapping("/contact")
    public Result getLinkedInFullContactInfo(@RequestParam(required = true) Long mid,
                                             @RequestParam(required = true) Long mt,
                                             @RequestParam(required = true) String fieldName) {
        try {
            // 获取当前用户信息
            Long userId = UserContext.getUserId();
            log.info("{} 正在查找LinkedIn联系人完整敏感信息，联系人ID: {}, 字段名: {}", userId, mid, fieldName);

            // 检查用户是否有权限查看完整联系信息
            // 查询用户额度
            UserBalance userBalance = userBalanceService.getByUserId(userId);
            if (userBalance == null || userBalance.getViewRecordsRemaining() < 1) {
                return Result.error("您的查看记录余额不足，请充值后再查看");
            }

            // 获取完整联系信息
            String contactInfo = linkedInUserService.getFullContactInfo(mid, mt, fieldName);

            // 检查联系人是否存在
            if (contactInfo == null) {
                return Result.error("联系人不存在或字段信息不存在");
            }

            // 增加LinkedIn搜索次数统计
            workbenchStatsService.incrementLinkedinSearchCount(userId);

            // 扣除用户查看记录余额
            userBalanceService.deductViewRecords(userId, 1);

            // 创建返回数据结构，与前端期望的格式匹配
            Map<String, String> resultData = new HashMap<>();
            resultData.put(fieldName, contactInfo);

            return Result.success(resultData);
        } catch (Exception e) {
            log.error("获取LinkedIn联系人敏感信息失败", e);
            return Result.error("获取联系人信息失败：" + e.getMessage());
        }
    }

    /**
     * 创建字段映射关系（支持国际化）
     *
     * @param language 语言代码（zh/en）
     * @return 字段名到对应语言标题的映射
     */
    private Map<String, String> createFieldMapping(String language) {
        Map<String, String> fieldMapping = new HashMap<>();
        boolean isEnglish = "en".equals(language);

        fieldMapping.put("fullName", isEnglish ? "Full Name" : "姓名");
        fieldMapping.put("jobTitle", isEnglish ? "Headline" : "职位");
        fieldMapping.put("companyName", isEnglish ? "Current Company" : "公司名称");
        fieldMapping.put("emails", isEnglish ? "Email" : "邮箱");
        fieldMapping.put("mobile", isEnglish ? "Phone" : "电话");
        fieldMapping.put("phoneNumbers", isEnglish ? "Other Phone" : "其他电话");
        fieldMapping.put("linkedinUrl", isEnglish ? "LinkedIn URL" : "LinkedIn链接");
        fieldMapping.put("companyWebsite", isEnglish ? "Company Website" : "公司网站");
        fieldMapping.put("industry", isEnglish ? "Industry" : "行业");
        fieldMapping.put("location", isEnglish ? "Location" : "地区");
        fieldMapping.put("country", isEnglish ? "Country" : "国家");
        fieldMapping.put("locationCountry", isEnglish ? "Country" : "国家");
        fieldMapping.put("countries", isEnglish ? "Countries" : "国家");
        fieldMapping.put("companySize", isEnglish ? "Company Size" : "公司规模");
        fieldMapping.put("companyFounded", isEnglish ? "Company Founded" : "公司成立时间");
        fieldMapping.put("twitterUserName", isEnglish ? "Twitter" : "Twitter");
        fieldMapping.put("twitterUrl", isEnglish ? "Twitter URL" : "Twitter链接");
        fieldMapping.put("githubUrl", isEnglish ? "GitHub" : "GitHub");
        fieldMapping.put("facebookUrl", isEnglish ? "Facebook" : "Facebook");
        return fieldMapping;
    }

    /**
     * 获取默认字段列表
     *
     * @return 默认字段数组
     */
    private String[] getDefaultFields() {
        return new String[]{
                "fullName", "jobTitle", "companyName", "emails", "mobile",
                "phoneNumbers", "linkedinUrl", "companyWebsite", "industry",
                "location", "locationCountry", "companySize", "companyFounded", "twitterUserName",
                "twitterUrl", "githubUrl", "facebookUrl"
        };
    }

    /**
     * 获取默认列名列表（支持国际化）
     *
     * @param language 语言代码（zh/en）
     * @return 默认列名数组
     */
    private String[] getDefaultColumnNames(String language) {
        boolean isEnglish = "en".equals(language);
        if (isEnglish) {
            return new String[]{
                    "Full Name", "Headline", "Current Company", "Email", "Phone",
                    "Other Phone", "LinkedIn URL", "Company Website", "Industry",
                    "Location", "Country", "Company Size", "Company Founded", "Twitter",
                    "Twitter URL", "GitHub", "Facebook"
            };
        } else {
            return new String[]{
                    "姓名", "职位", "公司名称", "邮箱", "电话",
                    "其他电话", "LinkedIn链接", "公司网站", "行业",
                    "地区", "国家", "公司规模", "公司成立时间", "Twitter",
                    "Twitter链接", "GitHub", "Facebook"
            };
        }
    }

    /**
     * 获取需要标红的重要字段列表
     *
     * @param selectedFields 用户选中的字段列表
     * @return 需要标红的字段数组（只包含用户选中的重要字段）
     */
    private String[] getHighlightFields(String[] selectedFields) {
        // 定义重要字段列表（需要标红的字段）
        String[] importantFields = {
                "fullName",      // 姓名
                "emails",        // 邮箱
                "mobile",        // 电话
                "linkedinUrl"    // LinkedIn链接
        };

        List<String> highlightFields = new ArrayList<>();
        Set<String> selectedFieldSet = new HashSet<>(Arrays.asList(selectedFields));

        // 只有当重要字段被用户选中时，才加入标红列表
        for (String importantField : importantFields) {
            if (selectedFieldSet.contains(importantField)) {
                highlightFields.add(importantField);
            }
        }

        return highlightFields.toArray(new String[0]);
    }

    /**
     * 获取公司信息
     */
    @GetMapping("/es/companies")
    public Result searchCompanies(@RequestParam(required = true) String keyword) {
        List<String> companies = linkedInUserService.searchCompanies(keyword);

        return Result.success(companies);
    }

    /**
     * 获取职位信息
     */
    @GetMapping("/es/jobtitles")
    public Result searchJobTitles(@RequestParam(required = true) String keyword) {
        List<String> jobTitles = linkedInUserService.searchJobTitles(keyword);

        return Result.success(jobTitles);
    }


    /**
     * 获取职位信息
     */
    @GetMapping("/es/industries")
    public Result searchIndustries(@RequestParam(required = true) String keyword) {
        List<String> industries = linkedInUserService.searchIndustries(keyword);

        return Result.success(industries);
    }

    /**
     * 获取职位信息
     */
    @GetMapping("/es/locations")
    public Result searchLocations(@RequestParam(required = true) String keyword) {
        List<String> locations = linkedInUserService.searchLocations(keyword);

        return Result.success(locations);
    }

}